package com.iot08.api.controller;

import com.alibaba.fastjson.JSONObject;
import com.iot08.api.constant.Constant;
import com.iot08.api.service.DevQQConfigService;
import com.iot08.api.service.DeviceService;
import com.iot08.api.utils.ZLOpensslSign;
import com.iot08.api.vo.request.WatchQQSignVO;
import com.iot08.api.vo.request.WatchWxSDKSignVO;
import com.iot08.common.entity.app.DevQQConfig;
import com.iot08.common.entity.app.Device;
import com.iot08.common.utils.HttpReq;
import com.iot08.common.utils.response.ResponseEnum;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.URL;
import java.util.Map;

/**
 * @version 1.0
 * @Description: 腾讯设备QQ获取guid 和 licenseId
 * @time: 2021/09/06 14:22
 * @author: weichao
 */
@RestController
@RequestMapping("getway")
@Slf4j
public class WatchQQSignController {

    @Resource
    private DevQQConfigService devQQConfigService;
    @Resource
    private DeviceService deviceService;

    @Value("${TXHLQQ_ToolPath}")
    private String TXHLQQ_ToolPath;
    @Value("${TXHLQQ_GUIDAndLicenseldFolderPath}")
    private String TXHLQQ_GUIDAndLicenseldFolderPath;
    @Value("${TXHLQQ_JYWATCHKEY}")
    private String TXHLQQ_JYWATCHKEY;

    @Value("${TXHLQQ_APPID}")
    private String TXHLQQ_APPID;

    @Value("${TXHLQQ_APPKey}")
    private String TXHLQQ_APPKey;

    //当前API 使用的域名
    @Value("${domain}")
    private String domaim;





    /**
     * 腾讯设备QQ获取基本信息
     *
     * @param vo 请求参数集合
     * @time: 2021/9/6 16:30
     * @author: weichao
     * @version 1.0
     */
    @GetMapping("qqlogin/watch/getbaseinfo")
    public ResponseMap watchQQSign(WatchQQSignVO vo,
                                   BindingResult bindingResult) {


        //认证 sign
        ResponseMap resOB = new ResponseMap();
        String key = DigestUtils.md5Hex(TXHLQQ_JYWATCHKEY + vo.getT()).toUpperCase();
        if (!key.equals(vo.getSign().toUpperCase())) {
            log.info("认证失败.sign值错误, sign:{}, timestamp: {}", vo.getSign(), vo.getT());
            return ResponseMap.fail("认证失败.sign值错误");
        }
        String imei = vo.getImei();

        String GUIDFilePath = TXHLQQ_GUIDAndLicenseldFolderPath+imei+"guid.txt";
        String LicenseldFilePath = TXHLQQ_GUIDAndLicenseldFolderPath+imei+"licenseld.txt";
        DevQQConfig devQQConfig = devQQConfigService.findById(imei);
        String deviceLicenseld = "";
        String GUID = "";
        try {
            if(devQQConfig == null){
                //创建一个
                //创建 GUID 和 Licenseld
                GUID = ZLOpensslSign.getGUIDWithImei(imei, GUIDFilePath);
                deviceLicenseld = ZLOpensslSign.getLicenseWithGUID(TXHLQQ_ToolPath, GUIDFilePath, LicenseldFilePath);
                devQQConfigService.add(imei, GUID, GUIDFilePath, deviceLicenseld, LicenseldFilePath);
            }else{
                deviceLicenseld = devQQConfig.getLicenseld();
                GUID = devQQConfig.getGuid();
                if(StringUtils.isEmpty(deviceLicenseld)){
                    GUID = ZLOpensslSign.getGUIDWithImei(imei, GUIDFilePath);
                    deviceLicenseld = ZLOpensslSign.getLicenseWithGUID(TXHLQQ_ToolPath, GUIDFilePath, LicenseldFilePath);
                    JSONObject updataMap = new JSONObject();
                    updataMap.put("licenseld", deviceLicenseld);
                    updataMap.put("guid", GUID);
                    devQQConfigService.update(imei, updataMap);
                }
            }
        }catch (Exception error){
            resOB.put("status", -1);
            resOB.put("msg", "服务器创建 GUID 和 Licenseld 时出错, error:"+error.getMessage());
            log.error("imei: "+imei+" 服务器创建 GUID 和 Licenseld 时出错, error:"+error.getMessage(),error);
            return resOB;
        }

        resOB.put("msg", String.format("%s,%s", GUID, deviceLicenseld));
        resOB.put("status", 0);
        log.info("imei:{} 腾讯设备QQ获取基本信息 返回resOB:{}", imei, resOB);
        return resOB;
    }

    /**
     * 腾讯设备QQ通过 认证code 获取 用户openid 和登录凭证 accesstoken
     *
     * @param paramsMap 请求参数集合
     * @time: 2021/09/6 18:30
     * @author: weichao
     * @version 1.0
     */
    @PostMapping("qqlogin/watch/loginthird")
    @ResponseBody
    public ResponseMap watchQQLoginthird(@RequestBody Map<String,Object> paramsMap, HttpServletRequest request) {
        String code = paramsMap.get("code").toString();
        String imei = paramsMap.get("imei").toString();
        if(code == null){
            ResponseMap failMap = new ResponseMap();
            failMap.put("result", -1);
            failMap.put("err_msg", "获取不到参数 code");
            return failMap;
        }

        //根据Code 去进行换取 accesstoken 和 openid
        /*
        * 第一步:
        * 参考: https://wiki.connect.qq.com/%e4%bd%bf%e7%94%a8authorization_code%e8%8e%b7%e5%8f%96access_token        *
        * 其中的Step2：通过Authorization Code获取Access Token
        * 第二步: https://wiki.connect.qq.com/%E8%8E%B7%E5%8F%96%E7%94%A8%E6%88%B7openid_oauth2-0
        * 使用accesstoken 得到 openid
        * */
        // 第一步 使用code 换取 accesstoken
        //https://graph.qq.com/oauth2.0/token
        String reqURL = "https://graph.qq.com/oauth2.0/token";
        //参数
        reqURL += "?grant_type=authorization_code";
        reqURL += "&client_id="+TXHLQQ_APPID;
        reqURL += "&client_secret="+TXHLQQ_APPKey;
        reqURL += "&code="+code;
        reqURL += "&redirect_uri=http://"+domaim+"/getway/qqlogin/watch/callback";
        reqURL += "&fmt=json";
        String res = HttpReq.sendGet(reqURL);
        log.info("imei:{} 向腾讯后台服务请求使用code 换取 accesstoken URL:{} 返回值:{}", imei, reqURL, res);
        JSONObject resOB = JSONObject.parseObject(res);
        String access_token = resOB.getString("access_token");
        if(access_token == null){
            ResponseMap errMap = new ResponseMap();
            errMap.put("result",-1);
            errMap.put("msg","使用code 换取accesstoken失败");
            log.info("使用code 换取accesstoken失败 res:{}",res);
            return errMap;
        }

        JSONObject updateMap = new JSONObject();
        updateMap.put("access_token", access_token);
        // accesstoken 过期的时间戳
        long expires_in = Long.valueOf(resOB.getString("expires_in"));
        long temp = System.currentTimeMillis()/1000  + expires_in;
        updateMap.put("accesstoken_expires", temp);
        // 刷新的accesstoken 必备的参数
        updateMap.put("refresh_token", resOB.get("refresh_token"));
        // 第二步 使用accesstoken 得到 openid
        //https://graph.qq.com/oauth2.0/me
        String getOpenidURL = "https://graph.qq.com/oauth2.0/me";
        getOpenidURL += "?access_token="+access_token+"&fmt=json";
        String getOpenidRes = HttpReq.sendGet(getOpenidURL);
        log.info("imei:{} 向腾讯后台服务请求使用accesstoken 获取openid URL:{} 返回值:{}", imei, getOpenidRes, getOpenidRes);
        JSONObject openidResOB = JSONObject.parseObject(getOpenidRes);
        String openid = openidResOB.getString("openid");
        if(openid == null){
            String msg = openidResOB.getString("msg");
            String errCode = openidResOB.getString("code");
            log.info("使用accesstoken 换取 openid的接口请求失败: errCode:{} msg:{}", errCode, msg);
            ResponseMap errMap = new ResponseMap();
            errMap.put("result",-1);
            errMap.put("msg","使用accesstoken 换取openid失败");
            return errMap;
        }

        //保存
        devQQConfigService.update(imei,updateMap);

        ResponseMap map = new ResponseMap();
        map.put("access_token", access_token);
        map.put("openid", openid);
        map.put("result", 1);
        log.info("imei:{} 腾讯设备QQ通过 认证code 获取 用户openid 和登录凭证 accesstoken 返回map:{}", imei, map);
        return map;
    }

    /**
     * 腾讯设备QQ回调地址
     *
     * @param request
     * @time: 2021/09/6 18:30
     * @author: weichao
     * @version 1.0
     */
    @GetMapping("qqlogin/watch/callback")
    public ResponseMap watchQQcallback(HttpServletRequest request) {
        log.info("腾讯设备QQ回调地址: 回调参数 request:{} ",request.getRequestURI());
        return ResponseMap.success();
    }

    public static void main(String[] args){

    }

}
